namespace ScrumSprintMonitor.Implementation
{
	#region #using Directives

	using System;

	using Infrastructure;

	using Ninject.Core;
	using Ninject.Core.Parameters;

	#endregion

	public class ConnectionProvider : IConnectionProvider,
	                                  IDisposable
	{
		private readonly IKernel kernel;
		private IConnection connection;
		private string serverName;

		public ConnectionProvider(IKernel kernel)
		{
			this.kernel = kernel;
		}

		#region Implementation of IConnectionProvider

		public IConnection ProvideConnectionTo(string requestedServerName, bool reuseExisting)
		{
			if (reuseExisting && string.Compare(requestedServerName, this.serverName, StringComparison.InvariantCultureIgnoreCase) == 0)
			{
				return this.connection;
			}

			var requestedConnection = this.kernel.Get<IConnection>(With.Parameters.ConstructorArgument("serverName", requestedServerName));

			DisposeConnections();

			this.serverName = requestedServerName;
			this.connection = requestedConnection;

			return this.connection;
		}

		private void DisposeConnections()
		{
			var disposable = this.connection as IDisposable;
			if (disposable != null)
			{
				disposable.Dispose();
			}

			this.serverName = null;
			this.connection = null;
		}

		#endregion

		#region Implementation of IDisposable

		public void Dispose()
		{
			DisposeConnections();
		}

		#endregion
	}
}